<?php
// +----------------------------------------------------------------------
// | 订单查询
// +----------------------------------------------------------------------
// | Author: @蓝优 荣誉出品
// +----------------------------------------------------------------------
class WxPayOrderQuery {
    private $appid;
    private $mchid;
    private $key;

    public function __construct($appid, $mchid, $key) {
        $this->appid = $appid;
        $this->mchid = $mchid;
        $this->key = $key;
    }

    /**
     * 查询订单状态
     *
     * @param string $out_trade_no 外部订单号
     * @return array 订单查询结果
     */
    public function queryOrder($out_trade_no) {
        $params = $this->prepareParams($out_trade_no);
        $xml = $this->arrayToXml($params);
        $response = $this->postXmlCurl($xml, 'https://api.mch.weixin.qq.com/pay/orderquery');
        
        if ($response === false) {
            // 处理CURL错误，例如记录日志或者返回错误信息
            return ['error' => 'CURL request failed!'];
        }

        $result = $this->xmlToArray($response);
        return $result;
    }

    /**
     * 准备请求参数
     *
     * @param string $out_trade_no 外部订单号
     * @return array 请求参数数组
     */
    private function prepareParams($out_trade_no) {
        $params = [
            'appid' => $this->appid,
            'mch_id' => $this->mchid,
            'out_trade_no' => $out_trade_no,
            'nonce_str' => $this->generateNonceStr(),
        ];
        $params['sign'] = $this->generateSign($params);

        return $params;
    }

    /**
     * 生成随机字符串
     *
     * @return string 随机字符串
     */
    private function generateNonceStr() {
        return md5(uniqid());
    }

    /**
     * 生成签名
     *
     * @param array $params 请求参数
     * @return string 签名字符串
     */
    private function generateSign($params) {
        ksort($params);
        $string = '';
        foreach ($params as $key => $value) {
            if ($value !== '' && !is_array($value)) {
                $string .= $key . '=' . $value . '&';
            }
        }
        $string .= 'key=' . $this->key;
        return strtoupper(md5($string));
    }

    /**
     * 转换参数数组为XML
     *
     * @param array $array 参数数组
     * @return string XML字符串
     */
    private function arrayToXml($array) {
        $xml = '<xml>';
        foreach ($array as $key => $value) {
            $xml .= '<' . $key . '>' . $value . '</' . $key . '>';
        }
        $xml .= '</xml>';
        return $xml;
    }

    /**
     * 使用CURL发送XML请求
     *
     * @param string $xml XML请求字符串
     * @param string $url 请求URL
     * @return mixed 响应结果或false
     */
    private function postXmlCurl($xml, $url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        $response = curl_exec($ch);
        curl_close($ch);

        return $response;
    }

    /**
     * 将XML转换为数组
     *
     * @param string $xml XML响应字符串
     * @return array 响应数组
     */
    private function xmlToArray($xml) {
        $array = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array;
    }
}

// 你的微信支付商户信息
$appid = '你的appid';
$mch_id = '你的商户号';
$key = '你的密钥';

// 实例化WxPayOrderQuery类
$wxOrderQuery = new WxPayOrderQuery($appid, $mch_id, $key);

// 获取外部订单号
$out_trade_no = $_GET['out_trade_no'];

// 查询订单状态
$result = $wxOrderQuery->queryOrder($out_trade_no);

// 判断订单是否支付成功
if (isset($result['error'])) {
    // 处理错误情况
    echo json_encode(['status' => 'error', 'message' => $result['error']]);
} elseif ($result['return_code'] == 'SUCCESS' && isset($result['trade_state']) && $result['trade_state'] == 'SUCCESS') {
    // 订单支付成功
    echo json_encode(['status' => 'success', 'message' => 'Order paid successfully!']);
} else {
    // 订单未支付成功，返回订单查询结果
    echo json_encode($result);
}